[新機能]Amazon Elasticsearch Service でファイルベースのシノニム、ユーザー辞書などに対応するカスタムパッケージを利用可能になりました
先日(2020年4月21日)、Amazon Elasticsearch Service がファイルベースのシノニム、ユーザー辞書などに対応するカスタムパッケージを利用可能になりました。
- Custom dictionary files now supported on Amazon Elasticsearch Service
- Custom Packages for Amazon Elasticsearch Service
全文検索と検索性能
EC サイトやブログサイトなどで全文検索による検索機能を提供するのは一般的になってきました。 Elasticsearch などの検索エンジンを利用することで全文検索を簡単に実装できます。
ただし、検索エンジンを利用したからといってユーザーにとって良い検索になるとは限りません。 提供する UI、扱うデータ、利用するユーザーによって検索の良し悪しは大きく変わります。 全てのユーザーにとって 100点の検索機能を提供することはほぼ不可能です。
一般的に良い検索(検索性能)は再現率、適合率で評価します。
扱うデータや利用するユーザーに合わせて検索性能を改善していくことは大変な作業です。 今回のアップデートは再現率、適合率を向上させる(場合によって低下させる)機能になります。
ただ実際のユーザーが評価する検索性能は再現率、適合率のヒットした/しないだけではなく、 UI だったり、スコアリングやソートといった様々な要因があることも忘れてはいけません。 これらの話はまた別の機会に記事を書きたいと思います。
Elasticsearch におけるシノニムとユーザー辞書
Elasticsearch で全文検索する場合、保持するデータを Analyzer を通して生成された用語のインデックスから、 クエリキーワードを Analyzer を通して生成された用語で検索します。
これらの Analyzer に適切なシノニム、ユーザー辞書を利用することで検索性能を向上できます。
シノニム
シノニムについては以前以下のブログを書きましたので詳しくはそちらを参照ください。
ユーザー辞書
Elasticsearch は日本語向け言語処理 Plugin として Japanese(kuromoji) Analysis Plugin を提供します。
ちなみに Elasticsearch で利用可能な日本語向け言語処理 Plugin は kuromoji の他に以下があります。
Amazon Elasticsearch Service を利用する場合、選択肢は kuromoji のみとなります。
kuromoji はベースとなる辞書が長らく更新されていなかったり、登録されている単語が少なかったりなので、 業務で利用する場合、期待する言語処理結果を得られないことが多々あります。
それにより再現率、適合率を下げる要因となります。
ユーザー辞書はベースの辞書では不足している単語を独自に追加できる機能です。
ユーザー辞書に単語を登録することで検索ヒットしてほしいものを返すことができ、 逆に正しく言語処理することでノイズが入りづらくできます。
シノニムをためしてみた
シノニムの定義ファイルのアップロードから実際に動作確認するところまで試してみましょう。 大きく以下の手順が必要です。
- (ドメイン作成していなければ)Amazon Elasticsearch Service のドメイン作成
- S3 にファイルアップロード
- Package のインポート
- Package とドメインの関連付け
- Analyzer に設定して動作確認
クラスメソッド株式会社は「クラメソ」と略されたり、「classmethod」と英語表記で検索されるケースがあります。 どれで検索されてもヒットするようにシノニムとして扱ってみましょう。
Amazon Elasticsearch Service のドメイン作成
今回は Amazon Elasticsearch Service が提供する最も新しいバージョンの 7.4 で作成しました。
特にバージョンを指定した記載はないのでどのバージョンでも利用可能なのかな。
S3 にファイルアップロード
今回は以下のようなシノニムファイルを用意しました。
クラスメソッド,クラメソ,classmethod
S3 にアップロードします。
$ aws s3 cp synonym.txt s3://es-custom-dictionary-fujimoto/ upload: ./synonym.txt to s3://es-custom-dictionary-fujimoto/synonym.txt
Package のインポート
Amazon Elasticsearch Service のドメイン画面を見ると「Packages」タグが作成されています。 こちらをクリックします。
「Associate」をクリックします。
まだ Package が作成されていないので何も表示されません。「Import」をクリックします。
パッケージ名とアップロードした S3 のパスを指定し、「Import」をクリックします。
Package の Import が完了しました。
Package とドメインの関連付け
Package をドメインに関連付けます。「Associate to a domain」をクリックします。
関連付けるドメインを選択し、「Associate」をクリックします。
関連付けが開始されます。
関連付けが完了すると Reference path が払い出されます。
このパスをシノニムフィルターのファイルパスに利用します。
Analyzer に設定して動作確認
それではアップロードしたシノニムを利用できるか確認します。
今回は結果がわかりやすいように Kibana の DevTool から POST _analyze
API を利用して確認します。
「クラスメソッド」の文字列の言語処理結果に「クラメソ」「classmethod」が追加されました。これで「クラスメソッド」を探しやすくなりましたね。
ユーザー辞書をためしてみた
先ほどの Analyze の結果、「クラスメソッド」は「クラス」、「メソッド」に単語分けされました。 会社名として扱う場合、「クラス」、もしくは「メソッド」のみでヒットするとノイズになるケースがあります。 「クラスメソッド」は「クラスメソッド」でのみヒットするようにユーザー辞書に登録してみましょう。
ユーザー辞書も手順は同じなので動作確認のところだけ記載します。
Analyzer に設定して動作確認
作成したユーザー辞書
クラスメソッド,クラスメソッド,クラスメソッド,カスタム名詞
確認結果
「クラスメソッド」の文字列の言語処理結果がシノニムに加えて「クラスメソッド」で返ってきました。これで呼んでない時に「クラスメソッド」は返ってこなくなりました。
パッケージのアップデート
注意が必要なのがアップデートです。
Elasticsearch のシノニム、ユーザー辞書はファイルを入れ替えて、インデックスをクローズ/オープンすると、 新しいファイルをロードします。 (転置インデックスのインデックスが変わるわけではないのでユーザー辞書では実質使えないけど)
Amazon Elasticsearch Service はオープン、クローズの API を提供していなかったり、パッケージの更新ができないため、同じことができません。
そこでインデックスレベルの切り替えが必要になります。
- 更新ファイルでパッケージを新規作成
- インデックスを新規作成(そこで更新ファイルのパッケージを利用)
- 新規インデックスにデータを登録(Reindex とかで)
まとめ
私が開発に携わっている Prismatix は検索機能に Elasticsearch を利用しています。 元々、Amazon Elasticsearch Service を利用していましたがユーザーからシノニムやユーザー辞書の要望が多く、 現在は Elasticsearch on EC2 で提供しています。
これを機に Amazon Elasticsearch Service への載せ替えを再検討したいな、と思いました。 同じようなユーザーがいたらぜひ検討してみてはいかがでしょうか。